package com.tpshion.cloud.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tpshion.cloud.auth.domain.dto.QueryRoleDto;
import com.tpshion.cloud.auth.domain.dto.SetRoleMenuDto;
import com.tpshion.cloud.auth.domain.dto.SetRolePermissionDto;
import com.tpshion.cloud.auth.domain.entity.Menu;
import com.tpshion.cloud.auth.domain.entity.Role;
import com.tpshion.cloud.auth.domain.entity.RoleMenu;
import com.tpshion.cloud.auth.domain.entity.RolePermission;
import com.tpshion.cloud.auth.mapper.*;
import com.tpshion.cloud.auth.service.RoleService;
import com.tpshion.cloud.auth.utils.MenuUtil;
import com.tpshion.cloud.auth.utils.support.MenuData;
import com.tpshion.cloud.common.support.Assert;
import com.tpshion.cloud.common.support.ErrorCode;
import com.tpshion.cloud.common.utils.IdUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RoleUserMapper roleUserMapper;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    @Autowired
    private MenuMapper menuMapper;

    @Override
    public PageInfo getPageRoles(QueryRoleDto queryRoleDto) {
        PageHelper.startPage(queryRoleDto.getPageNum(),queryRoleDto.getPageSize());
        QueryWrapper<Role> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("create_time");
        if(!StringUtils.isEmpty(queryRoleDto.getRoleName())){
            queryWrapper.like("role_name",queryRoleDto.getRoleName());
        }
        List<Role> roleList = roleMapper.selectList(queryWrapper);
        return new PageInfo(roleList);
    }

    @Override
    @Transactional
    public void deleteRole(String roleId) {
        roleMapper.deleteById(roleId);
        Map<String,Object> param = new HashMap<>();
        param.put("role_id",roleId);
        roleMenuMapper.deleteByMap(param);
        roleUserMapper.deleteByMap(param);
        rolePermissionMapper.deleteByMap(param);
    }

    @Override
    public List<MenuData> getRoleMenuData(String roleId) {
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("create_time");
        List<Menu> menus = menuMapper.selectList(queryWrapper);

        List<Menu> roleMenus = menuMapper.findByRoleId(roleId);

        List<String> menuIds = roleMenus.stream().map(Menu::getId).collect(Collectors.toList());

        List<MenuData> menuDataList = MenuUtil.getMenuData(menus,menuIds);
        return menuDataList;
    }

    @Override
    @Transactional
    public void setRoleMenuData(SetRoleMenuDto setRoleMenuDto) {
        Map<String,Object> param = new HashMap<>();
        param.put("role_id",setRoleMenuDto.getRoleId());
        roleMenuMapper.deleteByMap(param);
        if(CollectionUtils.isEmpty(setRoleMenuDto.getMenuIds())){
            // 不分配任何菜单
            return;
        }else{
            // 根据菜单id分配菜单
            setRoleMenuDto.getMenuIds().stream().forEach(item -> {
                RoleMenu roleMenu = new RoleMenu();
                roleMenu.setId(IdUtil.getUUID());
                roleMenu.setRoleId(setRoleMenuDto.getRoleId());
                roleMenu.setMenuId(item);
                roleMenuMapper.insert(roleMenu);
            });
        }
    }

    /**
     * 分配角色功能权限
     * @param setRolePermissionDto
     */
    @Override
    @Transactional
    public void setRolePermission(SetRolePermissionDto setRolePermissionDto) {
        // 判断角色是否存在
        Role role = roleMapper.selectById(setRolePermissionDto.getRoleId());
        Assert.notNull(role, ErrorCode.ROLE_NOT_EXIST);
        // 清除角色所有权限关系
        QueryWrapper<RolePermission> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id", role.getId());
        rolePermissionMapper.delete(queryWrapper);
        // 添加新的角色权限关系
        List<String> permissionIds = setRolePermissionDto.getPermissionIds();
        if(CollectionUtils.isEmpty(permissionIds)){
            // 不分配任何功能权限
            return;
        }else{
            // 根据权限id分配权限
            permissionIds.stream().forEach(permissionId -> {
                RolePermission rolePermission = new RolePermission();
                rolePermission.setId(IdUtil.getUUID());
                rolePermission.setRoleId(role.getId());
                rolePermission.setPermissionId(permissionId);
                rolePermissionMapper.insert(rolePermission);
            });
        }
    }
}
